﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using popLib.CustomeControl;
using System.Data.Objects;

namespace popLib.ModelSystem
{
    public partial class ListBase : Form
    {
        public FormAction Action { get; set; }

        public object SelectedID { get; set; }

        public object SelectedItem { get; set; }

        public IQueryable<dynamic> DataSource { get; set; }

        public string SelectedColumnName { get; set; }//ten cua property se duoc lay value de gan cho SelectedID

        public DataGridViewColumn[] DataColumns { get; set; }

        public SearchBox[] SearchControls { get; set; }

        public int ItemPerPage { get; set; }

        public int OwnerSearchBoxIndex { get; set; } //danh cho search nguoi lap chung tu, neu co thi se gan quyen view record owner/view record cho field nay
        public SearchBox OwnerSearchBox
        {
            get
            {
                if (OwnerSearchBoxIndex == null || OwnerSearchBoxIndex < 0)
                    return null;
                else
                    return SearchControls[OwnerSearchBoxIndex];
            }
        }

        public delegate ReturnSet SearchDelegateFunction(int page, int itemPerPage, Hashtable searchData);

        public SearchDelegateFunction SearchFunction { get; set; }

        public Type DetailFormType { get; set; }

        public FormLanguage Language { get; set; }

        public bool DisableTextBoxListUpDown { get; set; }

        public ListBase()
        {
            InitializeComponent();

            Action = new FormAction(true);
        }

        public ListBase(string title, FormAction action)
        {
            InitializeComponent();

            Action = action;

            this.Text = title;
        }

        public ListBase(FormAction action)
        {
            InitializeComponent();

            Action = action;
        }

        #region Event Functions
        private void BH_Ngoai_List_Load(object sender, EventArgs e)
        {
            FormLoad();
        }

        private void pageBar1_PageChanged(int page)
        {
            Search(page);
        }

        private void btn_select_Click(object sender, EventArgs e)
        {
            ButtonSelect();
        }

        private void btn_new_Click(object sender, EventArgs e)
        {
            ButtonNew();
        }

        private void btn_view_Click(object sender, EventArgs e)
        {
            ButtonView();
        }

        private void btn_search_Click(object sender, EventArgs e)
        {
            ButtonSearch();
        }

        private void dgv_list_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (btn_select.Visible)
            {
                ButtonSelect();
            }
            else if (btn_view.Visible)
            {
                ButtonView();
            }
        }
        #endregion

        #region Handle Functions
        public virtual void FormLoad()
        {
            //init datagridview columns
            dgv_list_Control.AutoGenerateColumns = false;
            DataLib.InitDataGridView(dgv_list_Control, DataColumns);

            //add search control to interface
            flp_container.Controls.Remove(flp_command);
            foreach (SearchBox control in SearchControls)
            {
                if( !DisableTextBoxListUpDown && control.BoxType == SearchBox.SearchBoxType.TextBox )
                    Global.InitTextBoxListUpDown( new Control[]{ control.DataControls[0] }, dgv_list_Control);

                flp_container.Controls.Add(control);
            }
            flp_container.Controls.Add(flp_command);


            //apply control tab index
            FormLib.UpdateControlTabIndex(flp_command.Controls, SearchControls[0]);

            UpdateFormAction();

            Search(1);

            //neu co add param thi add moi record lun
            if (Action.ExtraParam.isValid() && Action.ExtraParam.Contains("[ADD]"))
            {
                btn_new.PerformClick();
            }

            var timer = new Timer();
            timer.Interval = 100;
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            var timer = (Timer)sender;
            timer.Stop();
            ListBase_Resize(null, new EventArgs());
        }

        public virtual void ButtonSearch()
        {
            Search(1);
        }

        public bool updateSelectedItem()
        {
            if (dgv_list_Control.CurrentRow == null || dgv_list_Control.CurrentRow.Index < 0) return false;

            SelectedItem = DataSource.ToList()[dgv_list_Control.CurrentRow.Index];

            SelectedID = SelectedItem.GetType().GetProperty(SelectedColumnName).GetValue(SelectedItem, null);

            return true;
        }

        public virtual void ButtonSelect()
        {
            if (updateSelectedItem())
            {
                this.DialogResult = System.Windows.Forms.DialogResult.OK;
                this.Close();
            }
        }

        public virtual void ButtonNew()
        {
            if (DetailFormType == null) return;

            if (IsMdiChild)
            {
                ReturnSet rs = MainFormModel.Instance.ShowExistedWindow(DetailFormType);
                if (rs.Success)
                {
                    dynamic form1 = rs.Result;
                    form1.ExecuteAddNew();
                    return;
                }

                dynamic form = Activator.CreateInstance(DetailFormType, new object[] { Action });
                MainFormModel.Instance.AddMDIChild(form);
                form.FormClosed += new FormClosedEventHandler(DetailForm_FormClosed);
            }
            else
            {
                dynamic form = Activator.CreateInstance(DetailFormType, new object[] { Action });                
                form.FormClosed += new FormClosedEventHandler(DetailForm_FormClosed);
                form.ShowDialog();
            }
        }

        void DetailForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            dynamic form = sender;

            if (form.IsDatabaseChanged)
            {
                PageBarControl.RefreshData();
            }
        }

        public virtual void ButtonView()
        {
            if (!updateSelectedItem()) return;

            if (DetailFormType == null) return;

            // neu la form form con cua MainForm thi show form trong mainform
            if (IsMdiChild)
            {
                ReturnSet rs = MainFormModel.Instance.ShowExistedWindow(DetailFormType);
                if (rs.Success)
                {
                    dynamic form1 = rs.Result;
                    form1.ExecuteViewDetail(SelectedID);
                    return;
                }

                dynamic form = Activator.CreateInstance(DetailFormType, new object[] { Action, SelectedID });
                MainFormModel.Instance.AddMDIChild(form);
                form.FormClosed += new FormClosedEventHandler(DetailForm_FormClosed);
            }
            else
            {
                dynamic form = Activator.CreateInstance(DetailFormType, new object[] { Action, SelectedID });
                form.FormClosed += new FormClosedEventHandler(DetailForm_FormClosed);
                form.ShowDialog();
            }
        }

        public virtual void UpdateFormAction()
        {
            btn_new.Visible = Action.AddRecord;
            btn_select.Visible = Action.SelectRecord;
            btn_view.Visible = Action.ViewRecord || Action.ViewRecordOwner;

            if (OwnerSearchBox != null)
            {
                OwnerSearchBox.DataControls[0].Text = MainFormModel.Instance.CurrentUser.Username;

                if (Action.ViewRecord == false && Action.ViewRecordOwner == true)
                {
                    OwnerSearchBox.DataControls[0].Enabled = false;
                }
            }

            Global.InitListFormButton(this, btn_select, btn_search, btn_view, btn_new, Language);
            PageBarControl.Language = Language;
        }

        public virtual void Search(int page)
        {
            Hashtable searchData = new Hashtable();

            Hashtable temp;

            foreach (Control control in flp_container.Controls)
            {
                if (control == flp_command) continue;

                temp = ((SearchBox)control).DataValue;

                foreach (string key in temp.Keys)
                {
                    searchData.Add(key, temp[key]);
                }
            }

            ReturnSet result = SearchFunction(page, ItemPerPage == 0 ? 100 : ItemPerPage, searchData);

            if (result.Success)
            {
                PageData pageData = (PageData)result.Result;
                PageBarControl.PageSource = pageData;

                DataSource = (IQueryable<dynamic>)PageBarControl.PageSource.DataSource;
                dgv_list_Control.DataSource = PageBarControl.PageSource.DataSource;
            }
        }
        #endregion

        public IQueryable<dynamic> HandleSearch(dynamic dataSet, Hashtable searchData)
        {
            return DataLib.HandleSearch(dataSet, searchData, SearchControls);
        }

        public ReturnSet ProcessPageData(int page, IQueryable<dynamic> result, int itemPerPage)
        {
            return DataLib.ProcessPageData(page, result, itemPerPage);
        }

        private void ListBase_Resize(object sender, EventArgs e)
        {
            //update container'size and location
            gbx_search.Size = new Size(this.Width - 32, flp_command.Location.Y + 60);
            dgv_list_Control.Location = new Point(dgv_list_Control.Location.X, gbx_search.Location.Y + gbx_search.Height + 10);
            dgv_list_Control.Size = new Size( this.Width - 32, PageBarControl.Location.Y - (gbx_search.Location.Y + gbx_search.Height) - 20);
        }
    }
}

